# # 定义一个学生类
# # 要求：
# # 1. 属性包括学生姓名、学号，以及语数英三科的成绩
# # 2. 能够设置学生某科目的成绩
# # 3. 能够打印出该学生的所有科目成绩
#
# class Student:
#     def __init__(self, name, student_id):
#         self.name = name
#         self.student_id = student_id
#         self.grades = {"语文": 0, "数学": 0, "英语": 0}
#
#     def set_grade(self, course, grade):
#         if course in self.grades:
#             self.grades[course] = grade
#
#     def print_grades(self):
#         print(f"学生{self.name} (学号：{self.student_id}) 的成绩为：")
#         for course in self.grades:
#             print(f"{course}: {self.grades[course]}分")
#
# # chen = Student("小陈", "100618")
# # chen.set_grade("语文", 92)
# # chen.set_grade("数学", 94)
# # chen.print_grades()
#
# ZhangKeDong = Student("张柯东","240523501047")
# ZhangKeDong.set_grade("语文","140")
# ZhangKeDong.set_grade("数学","149")
# ZhangKeDong.set_grade("英语","49")
# ZhangKeDong.print_grades()
#
#
# # zeng = Student("小曾", "100622")
# # print(zeng.name)
# # zeng.set_grade("数学", 95)
# # print(zeng.grades)
from datetime import datetime
import random


class BankAccount:
    """银行账户类"""

    def __init__(self, account_holder, initial_balance=0, account_type="储蓄账户"):
        self.account_number = self._generate_account_number()
        self.account_holder = account_holder
        self.balance = initial_balance
        self.account_type = account_type
        self.transaction_history = []
        self.is_active = True
        self._add_transaction("开户", initial_balance, initial_balance)

    def _generate_account_number(self):
        """生成随机账号"""
        return f"622202{random.randint(1000000000, 9999999999)}"

    def _add_transaction(self, transaction_type, amount, balance_after):
        """添加交易记录"""
        transaction = {
            "date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "type": transaction_type,
            "amount": amount,
            "balance_after": balance_after
        }
        self.transaction_history.append(transaction)

    def deposit(self, amount):
        """存款"""
        if not self.is_active:
            print("账户已冻结，无法操作")
            return False

        if amount <= 0:
            print("存款金额必须大于0")
            return False

        self.balance += amount
        self._add_transaction("存款", amount, self.balance)
        print(f"成功存款 {amount:.2f}元，当前余额: {self.balance:.2f}元")
        return True

    def withdraw(self, amount):
        """取款"""
        if not self.is_active:
            print("账户已冻结，无法操作")
            return False

        if amount <= 0:
            print("取款金额必须大于0")
            return False

        if amount > self.balance:
            print("余额不足")
            return False

        self.balance -= amount
        self._add_transaction("取款", amount, self.balance)
        print(f"成功取款 {amount:.2f}元，当前余额: {self.balance:.2f}元")
        return True

    def transfer(self, target_account, amount):
        """转账"""
        if not self.is_active:
            print("账户已冻结，无法操作")
            return False

        if not target_account.is_active:
            print("目标账户已冻结，无法转账")
            return False

        if amount <= 0:
            print("转账金额必须大于0")
            return False

        if amount > self.balance:
            print("余额不足，无法转账")
            return False

        # 从当前账户扣款
        self.balance -= amount
        self._add_transaction(f"转账至{target_account.account_number}", amount, self.balance)

        # 向目标账户存款
        target_account.balance += amount
        target_account._add_transaction(f"来自{self.account_number}的转账", amount, target_account.balance)

        print(f"成功向 {target_account.account_holder} 转账 {amount:.2f}元")
        return True

    def get_balance(self):
        """查询余额"""
        return self.balance

    def get_transaction_history(self):
        """获取交易记录"""
        return self.transaction_history

    def print_statement(self):
        """打印对账单"""
        print(f"\n=== {self.account_holder} 的账户对账单 ===")
        print(f"账号: {self.account_number}")
        print(f"账户类型: {self.account_type}")
        print(f"当前余额: {self.balance:.2f}元")
        print(f"状态: {'正常' if self.is_active else '冻结'}")
        print("\n交易记录:")
        print("-" * 60)
        print(f"{'日期':<20} {'类型':<15} {'金额':<10} {'余额':<10}")
        print("-" * 60)

        for transaction in self.transaction_history:
            print(
                f"{transaction['date']:<20} {transaction['type']:<15} {transaction['amount']:<10.2f} {transaction['balance_after']:<10.2f}")

    def freeze_account(self):
        """冻结账户"""
        self.is_active = False
        print("账户已冻结")

    def unfreeze_account(self):
        """解冻账户"""
        self.is_active = True
        print("账户已解冻")

    def __str__(self):
        return f"账户: {self.account_number}, 户主: {self.account_holder}, 余额: {self.balance:.2f}元, 类型: {self.account_type}"


class SavingsAccount(BankAccount):
    """储蓄账户类，继承自BankAccount"""

    def __init__(self, account_holder, initial_balance=0, interest_rate=0.015):
        super().__init__(account_holder, initial_balance, "储蓄账户")
        self.interest_rate = interest_rate  # 年利率

    def calculate_interest(self, months):
        """计算利息"""
        if not self.is_active:
            print("账户已冻结，无法计算利息")
            return 0

        interest = self.balance * self.interest_rate * months / 12
        print(f"{months}个月后预计利息: {interest:.2f}元")
        return interest


class CheckingAccount(BankAccount):
    """支票账户类，继承自BankAccount"""

    def __init__(self, account_holder, initial_balance=0, overdraft_limit=1000):
        super().__init__(account_holder, initial_balance, "支票账户")
        self.overdraft_limit = overdraft_limit  # 透支额度

    def withdraw(self, amount):
        """重写取款方法，支持透支"""
        if not self.is_active:
            print("账户已冻结，无法操作")
            return False

        if amount <= 0:
            print("取款金额必须大于0")
            return False

        if amount > self.balance + self.overdraft_limit:
            print(f"超出透支额度，最大可取 {self.balance + self.overdraft_limit:.2f}元")
            return False

        self.balance -= amount
        self._add_transaction("取款", amount, self.balance)

        if self.balance < 0:
            print(f"成功取款 {amount:.2f}元，当前余额: {self.balance:.2f}元 (已透支)")
        else:
            print(f"成功取款 {amount:.2f}元，当前余额: {self.balance:.2f}元")

        return True


class Bank:
    """银行类"""

    def __init__(self, bank_name):
        self.bank_name = bank_name
        self.accounts = {}

    def create_account(self, account_holder, initial_balance=0, account_type="savings"):
        """创建账户"""
        if account_type == "savings":
            account = SavingsAccount(account_holder, initial_balance)
        elif account_type == "checking":
            account = CheckingAccount(account_holder, initial_balance)
        else:
            account = BankAccount(account_holder, initial_balance)

        self.accounts[account.account_number] = account
        print(f"成功为 {account_holder} 创建{account.account_type}，账号: {account.account_number}")
        return account

    def get_account(self, account_number):
        """根据账号获取账户"""
        return self.accounts.get(account_number)

    def close_account(self, account_number):
        """关闭账户"""
        if account_number in self.accounts:
            account = self.accounts[account_number]
            if account.balance == 0:
                del self.accounts[account_number]
                print(f"账户 {account_number} 已关闭")
                return True
            else:
                print("账户余额不为0，无法关闭")
                return False
        else:
            print("账户不存在")
            return False

    def list_accounts(self):
        """列出所有账户"""
        print(f"\n=== {self.bank_name} 账户列表 ===")
        if not self.accounts:
            print("暂无账户")
            return

        for account in self.accounts.values():
            print(account)


# 示例运行
def main():
    # 创建银行
    my_bank = Bank("中国银行")

    # 创建账户
    print("=== 创建账户 ===")
    account1 = my_bank.create_account("张三", 1000, "savings")
    account2 = my_bank.create_account("李四", 500, "checking")
    account3 = my_bank.create_account("王五", 2000)

    # 存款操作
    print("\n=== 存款操作 ===")
    account1.deposit(500)
    account2.deposit(300)

    # 取款操作
    print("\n=== 取款操作 ===")
    account1.withdraw(200)
    account2.withdraw(800)  # 测试支票账户透支功能

    # 转账操作
    print("\n=== 转账操作 ===")
    account1.transfer(account2, 300)

    # 储蓄账户计算利息
    print("\n=== 利息计算 ===")
    if isinstance(account1, SavingsAccount):
        account1.calculate_interest(12)  # 计算12个月利息

    # 账户管理
    print("\n=== 账户管理 ===")
    my_bank.list_accounts()

    # 打印对账单
    print("\n=== 账户对账单 ===")
    account1.print_statement()

    # 测试账户冻结
    print("\n=== 账户冻结测试 ===")
    account3.freeze_account()
    account3.deposit(100)  # 应该失败

    # 测试账户解冻
    print("\n=== 账户解冻测试 ===")
    account3.unfreeze_account()
    account3.deposit(100)  # 应该成功

    # 尝试关闭账户
    print("\n=== 关闭账户测试 ===")
    my_bank.close_account(account3.account_number)  # 应该失败，因为余额不为0

    # 清空账户3后再尝试关闭
    account3.withdraw(account3.get_balance())
    my_bank.close_account(account3.account_number)  # 应该成功


if __name__ == "__main__":
    main()